/**
 * *********************************************************************
 * FILENAME:
 *    rpc_client.c
 *
 * DESCRIPTION:
 *    rpc client
 *
 * AUTHOR:
 *    Tsihang
 *
 * CHANGE HISTORY:
 *    <date>        <author>    <desc>
 *    2012.08.16    Tsihang   create this file
 *
 * *********************************************************************
 */ 
#include "../inc/rpc_server.h"
#include "../inc/rpcGloableTables.h"
#include "../inc/rpc_sysInfo.h"
#include "../inc/sysConfig.h"

#ifndef debug0705
#define debug0705
#endif 

struct thread_master_rpc * master_rpc = NULL;


int cc_rpc_get_pkt_len(unsigned char *packet)
{
    RPC_HEAD_SERV_ST *pHead = (RPC_HEAD_SERV_ST*)packet;

    return pHead->pkt_len;
}

int cc_rpc_get_rpc_id(unsigned char *packet)
{
    RPC_HEAD_SERV_ST *pHead = (RPC_HEAD_SERV_ST*)packet;

    return pHead->rpc_id;
}

int cc_rpc_get_param_num(unsigned char *packet)
{
    RPC_HEAD_SERV_ST *pHead = (RPC_HEAD_SERV_ST*)packet;

    return pHead->param_num;
}

int cc_rpc_parse_request(unsigned char *request)
{
#if 0
    unsigned int rpc_id, params_num;
    //RPC_HEAD_SERV_ST *pHead = (RPC_HEAD_SERV_ST*)request;
    //RPC_PARAMS_SERV_ST *pParam = (RPC_PARAMS_SERV_ST*)(pHead + 1);
    int i;

    rpc_id = cc_rpc_get_rpc_id(request);
    params_num = cc_rpc_get_param_num(request);

    for (i = 0; i < params_num; i++)
    {
        
    }
#endif
    return 0;
}

void cc_rpc_parse_param(unsigned char *request, int *offset, unsigned char *result)
{
    RPC_PARAMS_SERV_ST *pParam = (RPC_PARAMS_SERV_ST *)(request + *offset);

    /*printf("\r\n type = %u length = %u value = %u \r\n",
        pParam->type, pParam->length, *((unsigned int *)pParam->value));*/

    memcpy(result, pParam->value, pParam->length-4);

    *offset += pParam->length;
}

int cc_rpc_generate_response(unsigned char *result, int len)
{
    unsigned char response[1024];
    RPC_HEAD_SERV_ST *pHead = (RPC_HEAD_SERV_ST*)response;

    pHead->version = 1;
    pHead->pkt_type = 2;
    pHead->pkt_len = len + sizeof(RPC_HEAD_SERV_ST);

    memcpy(response+sizeof(RPC_HEAD_SERV_ST), result, len);
    return 0;
}
int readRpcRequest(int rpcSock,unsigned char *request)
{
	int nbytes, pkt_len, offset = 0;
    	unsigned char buf[RPC_READ_BUF];
    	int first_flag = 1;

	while (1)
	{
		memset(buf, 0, RPC_READ_BUF);
		/* Read raw data from socket */
		nbytes = read(rpcSock, buf, RPC_READ_BUF - 1);
		if (nbytes <= 0)
		{
			RPCDebugOut("\r\n nbytes = %d \r\n",nbytes);
			//continue;
			return -1;
		 }
		/* length field of packet is in the first packet */
		if (first_flag == 1)
		{
			pkt_len = cc_rpc_get_pkt_len(buf);
			if (pkt_len > RPC_READ_BUF-1)
			{
				RPCDebugOut("\r\n cc packet length is too long \r\n");
			}
			first_flag = 0;
		}
		memcpy(request+offset,buf,nbytes);
		if (nbytes+offset != pkt_len)
		{
			offset += nbytes;
			continue;
		}
		else
		{
			break;
		}
	}
	return pkt_len;
}
int ExcuteMethod(unsigned char * request,unsigned char *result,int *return_param_num, int *return_bytes)
{
	int methodId;
	methodId = cc_rpc_get_rpc_id(request);
	RPCDebugOut("\r\n func = %s line = %d methoId = %d\r\n", __FUNCTION__, __LINE__, methodId);
	if(methodId < 0)
	{
		printf("methodId error\r\n");
	}
	if(methodId >= RPC_STAT_SYSINFO_START_ID && methodId <=RPC_STAT_SYSINFO_END_ID)
	{
		methodId = methodId % 100;
		RPCDebugOut("step into process mode: methodId=%d\r\n",methodId);
		(*pRpcGetSysInfo[methodId])(request,result,return_param_num,return_bytes);
	}
	else
	{
		printf("cc <ExcuteMethod> error methodId = %d\r\n",methodId);
	}
#if 0
/*Subscriber
#define RPC_SUBSCRIBER_START_ID 0
#define RPC_SUBSCRIBER_END_ID 99
*/
	else if(methodId >= RPC_SUBSCRIBER_START_ID && methodId <= RPC_SUBSCRIBER_END_ID)
	{
		/*RPCDebugOut("methodId = %d\r\n",methodId);*/
		methodId = methodId % 100;
		(*pRpcSubFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*Subscriber group
#define RPC_SUBSCRIBER_GROUP_START_ID 200
#define RPC_SUBSCRIBER_GROUP_END_ID 299
*/
	else if(methodId >= RPC_SUBSCRIBER_GROUP_START_ID && methodId <= RPC_SUBSCRIBER_GROUP_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcSubGrpFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*Application
#define RPC_APPLICATION_START_ID 400
#define RPC_APPLICATION_END_ID 499
*/
	else if(methodId >= RPC_APPLICATION_START_ID && methodId <= RPC_APPLICATION_END_ID)
	{
		/*printf("methodId = %d\r\n",methodId);*/
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcAppFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*Application group
#define RPC_APPLICATION_GROUP_START_ID 600
#define RPC_APPLICATION_GROUP_END_ID 699
*/
	else if(methodId >= RPC_APPLICATION_GROUP_START_ID && methodId <= RPC_APPLICATION_GROUP_END_ID)
	{
		/*printf("methodId = %d\r\n",methodId);*/
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcAppGrpFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*Session
#define RPC_SESSION_START_ID 800
#define RPC_SESSION_END_ID 899
*/
	else if(methodId >= RPC_SESSION_START_ID && methodId <= RPC_SESSION_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcSessionFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*Policy
#define RPC_POLICY_START_ID 1000
#define RPC_POLICY_END_ID 1099
*/
	else if(methodId >= RPC_POLICY_START_ID && methodId <= RPC_POLICY_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcPolFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*Pipe
#define RPC_PIPE_START_ID 1100
#define RPC_PIPE_END_ID 1199
*/
	else if(methodId >= RPC_PIPE_START_ID && methodId <=RPC_PIPE_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcPipeFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*Serve
#define RPC_SERVER_START_ID 1200
#define RPC_SERVER_END_ID 1299
r*/	
	else if(methodId >= RPC_SERVER_START_ID && methodId <=RPC_SERVER_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcServerFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*pos&ethernet
#define RPC_POS_ETHERNET_START_ID 1300
#define RPC_POS_ETHERNET_END_ID 1399
*/
	else if(methodId >= RPC_POS_ETHERNET_START_ID && methodId <=RPC_POS_ETHERNET_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcPosEthernetFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*statistics
#define RPC_STATISTICS_START_ID 1400
#define RPC_STATISTICS_END_ID 1499
*/
	else if(methodId >= RPC_STATISTICS_START_ID && methodId <=RPC_STATISTICS_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcStatisticsFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*stat_accsub
#define RPC_STAT_ACC_SUB_START_ID 1500
#define RPC_STAT_ACC_SUB_END_ID 1599
*/
	else if(methodId >= RPC_STAT_ACC_SUB_START_ID && methodId <=RPC_STAT_ACC_SUB_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcStatAccSubFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*stat_app
#define RPC_STAT_APP_START_ID 1600
#define RPC_STAT_APP_END_ID 1699
*/
	else if(methodId >= RPC_STAT_APP_START_ID && methodId <=RPC_STAT_APP_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcStatAppFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*stat_pol
#define RPC_STAT_POL_START_ID 1700
#define RPC_STAT_POL_END_ID 1799
*/
	else if(methodId >= RPC_STAT_POL_START_ID && methodId <=RPC_STAT_POL_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcStatPolFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*stat_sub
#define RPC_STAT_SUB_START_ID 1900
#define RPC_STAT_SUB_END_ID 1999
*/
	else if(methodId >= RPC_STAT_SUB_START_ID && methodId <=RPC_STAT_SUB_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcStatSubFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*Accounting Subscriber
#define RPC_ACC_SUB_START_ID 2000
#define RPC_ACC_SUB_END_ID 2099
*/
	else if(methodId >= RPC_ACC_SUB_START_ID && methodId <= RPC_ACC_SUB_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcAccSubFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*Package
#define RPC_PACKAGE_START_ID 2100
#define RPC_PACKAGE_END_ID 2199
*/
	else if(methodId >= RPC_PACKAGE_START_ID && methodId <= RPC_PACKAGE_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcPkgFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*System Start
#define RPC_SYS_START_ID 2200
#define RPC_SYS_END_ID 2299
*/
	else if(methodId >= RPC_SYS_START_ID && methodId <= RPC_SYS_END_ID)
	{
		/*RPCDebugOut("methodId = %d\r\n",methodId);*/
		methodId = methodId % 100;
		/*RPCDebugOut("methodId = %d\r\n",methodId);	*/	
		(*pRpcSysFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*others
#define RPC_OTHERS_START_ID 2300
#define RPC_OTHERS_END_ID 2399
*/
	else if(methodId >= RPC_OTHERS_START_ID && methodId <= RPC_OTHERS_END_ID)
	{
		RPCDebugOut("methodId = %d\r\n",methodId);
		methodId = methodId % 100;
		(*pRpcOthersFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*Bypass
#define RPC_BYPASS_START_ID 2400
#define RPC_BYPASS_END_ID 2499
*/
	else if(methodId >= RPC_BYPASS_START_ID && methodId <= RPC_BYPASS_END_ID)
	{
		/*RPCDebugOut("methodId = %d\r\n",methodId);*/
		methodId = methodId % 100;
		/*RPCDebugOut("methodId = %d\r\n",methodId);	*/	
		(*pRpcBypassFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*Skype
#define RPC_SKYPE_START_ID 2500
#define RPC_SKYPE_END_ID 2599
*/
	else if(methodId >= RPC_SKYPE_START_ID && methodId <= RPC_SKYPE_END_ID)
	{
		/*RPCDebugOut("methodId = %d\r\n",methodId);*/
		methodId = methodId % 100;
		/*RPCDebugOut("methodId = %d\r\n",methodId);	*/	
		(*pRpcSkypeFunc[methodId])(request,result,return_param_num,return_bytes);
	}
/*Skype
#define RPC_NETFLOW_START_ID 2600
#define RPC_NETFLOW_END_ID 2699
*/
	else if(methodId >= RPC_NETFLOW_START_ID && methodId <= RPC_NETFLOW_END_ID)
	{
		/*RPCDebugOut("methodId = %d\r\n",methodId);*/
		methodId = methodId % 100;
		/*RPCDebugOut("methodId = %d\r\n",methodId);	*/	
		(*pRpcNetflowFunc[methodId])(request,result,return_param_num,return_bytes);
	}
#endif
	return 0;
}
int cc_rpc_generate_head(unsigned char *result,int rpc_id,int return_param_num,int return_bytes)   
{
	RPC_HEAD_SERV_ST *temp = (RPC_HEAD_SERV_ST *)result;
	temp->version = 1;
	temp->pkt_type = RPC_RESPONSE;
	temp->pkt_len = return_bytes;
	temp->resv =0 ;
	temp->rpc_id = rpc_id;
	temp->param_num = return_param_num;
	return temp->pkt_len;
}

int sendResponse(int rpcSock,unsigned char * response,int responseLen)
{
	int wl,slice,resend = 0;
	if (responseLen<800)
	{
		wl = write(rpcSock, response, responseLen);
		resend =0;
		while ((wl != responseLen) && (resend<5))
		{
			RPCDebugOut("resend : w1=%d,len =%d\r\n",wl,responseLen);
			taskDelay(2);
			if(wl < 0)
				wl =0;
			wl += write(rpcSock, &response[wl], responseLen-wl);
			resend++;
		}
		if(wl!=responseLen)
		{
			RPCDebugOut("send error : w1=%d,responseLen =%d\r\n",wl,responseLen);
		}
		/*printf("cc _CCRadiusGet write %d bytes\r\n",wl);*/
	}
	else
	{
		for(slice=0;slice<(int)(responseLen/800);slice++)
		{
			wl = write(rpcSock,&response[slice*800], 800);
			resend = 0;
			while ((wl != 800) && (resend<5))
			{
				RPCDebugOut("resend : wl=%d,len = 800\r\n",wl);
				taskDelay(2);
				if(wl < 0)
					wl =0;
				wl += write(rpcSock, &response[wl], 800-wl);
				resend++;
			}
			if(wl!=800)
			{
				RPCDebugOut("send error : wl=%d,len =800\r\n",wl);
			}
			/*printf("cli SmisServSubmit write %d bytes\r\n",wl);*/
		}
		if ((responseLen-(slice*800))>0)
		{
			wl = write(rpcSock,&response[slice*800], responseLen-(slice*800));
			resend = 0;
			while ((wl != (responseLen-(slice*800))) && (resend<5))
			{
				RPCDebugOut("resend : wl=%d,len = %d\r\n",wl,responseLen-(slice*800));
				taskDelay(2);
				if(wl < 0)
					wl =0;
				wl += write(rpcSock, &response[wl], responseLen-(slice*800)-wl);
				resend++;
			}
			if(wl != (responseLen-(slice*800)))
			{
				RPCDebugOut("send error : wl=%d,len = %d\r\n",wl,(responseLen-(slice*800)));
			}
			/*printf("cli SmisServSubmit write %d bytes\r\n",wl);*/
		}
	}
	return 0;
}
void cc_rpc_generate_param(unsigned char *respons, int *offset, int *pkt_len, int type, int len, unsigned char *value)
{
    RPC_PARAMS_SERV_ST *pParam = (RPC_PARAMS_SERV_ST *)(respons + *offset);

    pParam->type = type;
    pParam->length = len;
    memcpy(pParam->value, value, len-4);

    *offset += len;
    *pkt_len += len;
}

/* Make socket from sockunion union. */
int rpc_sockunion_stream_socket (int libIndex, union sockunion *su)
{
  int sock;

  sock = socket (su->sa.sa_family, SOCK_STREAM, 0);

  if (sock < 0)
    /*zlog (libIndex, NULL, LOG_WARNING, "can't make socket sockunion_stream_socket")*/;

  return sock;
}

/* Bind socket to specified address. */
int rpc_sockunion_bind (int libIndex, int sock, union sockunion *su, unsigned short port, 
		union sockunion *su_addr)
{
  int size = 0;
  int ret;

  if (su->sa.sa_family == AF_INET)
    {
      size = sizeof (struct sockaddr_in);
      su->sin.sin_port = htons (port);
      if (su_addr == NULL)
	su->sin.sin_addr.s_addr = htonl (INADDR_ANY);
    }
  ret = bind (sock, (struct sockaddr *)su, size);
  if (ret < 0)
    /*zlog (libIndex, NULL, LOG_WARNING, "can't bind socket : %s", strerror (errno))*/;

  return ret;
}

int rpc_sockopt_reuseaddr (int libIndex, int sock)
{
  int ret;
  int on = 1;

  ret = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, 
		    (void *) &on, sizeof (on));
  if (ret < 0)
    {
      /*zlog (libIndex, NULL, LOG_WARNING, "can't set sockopt SO_REUSEADDR to socket %d", sock)*/;
      return -1;
    }
  return 0;
}

/* Sets/resets TCP options TCP_NODELAY for the socket.  */

int rpc_sockopt_nodelay(int sock)
{
  int ret;
  int on = 1;

  ret = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on));
  if (ret < 0)
    {
      /*zlog (libIndex, NULL, LOG_WARNING, "can't set sockopt TCP_NODELAY to socket %d", sock);*/
      return -1;
    }
  return 0;
}

#ifdef SO_REUSEPORT
int rpc_sockopt_reuseport (int libIndex, int sock)
{
  int ret;
  int on = 1;

  ret = setsockopt (sock, SOL_SOCKET, SO_REUSEPORT, 
		    (void *) &on, sizeof (on));
  if (ret < 0)
    {
      /*zlog (libIndex, NULL, LOG_WARNING, "can't set sockopt SO_REUSEADDR to socket %d", sock)*/;
      return -1;
    }
  return 0;
}
#else
int
rpc_sockopt_reuseport (int libIndex, int sock)
{
  return 0;
}
#endif /* 0 */

/* Return accepted new socket file descriptor. */
int rpc_sockunion_accept (int libIndex, int sock, union sockunion *su)
{
  socklen_t len;
  int client_sock;

  len = sizeof (union sockunion);
  client_sock = accept (sock, (struct sockaddr *) su, &len);
  
  /* Convert IPv4 compatible IPv6 address to IPv4 address. */

  return client_sock;
}

int rpc_accept (int libIndex, struct thread_rpc *thread)
{
    int rpc_sock;
    union sockunion su;
    int ret;
    unsigned int on;
    int accept_sock;

    accept_sock = RPC_THREAD_FD (thread);

    /* We continue hearing vty socket. */
    rpc_event (libIndex, RPC_SERV, accept_sock, NULL);

    memset (&su, 0, sizeof (union sockunion));

    /* We can handle IPv4 or IPv6 socket. */
    rpc_sock = rpc_sockunion_accept (libIndex, accept_sock, &su);
    if (rpc_sock < 0)
    {
        /*zlog_warn (libIndex, "can't accept vty socket : %s", strerror (errno));*/
		RPCDebugOut("\r\n func = %s line = %d accept connect request failure !\r\n", __FUNCTION__, __LINE__);
        	return -1;
    }
    RPCDebugOut("RPC socket = %d\n", rpc_sock);
    on = 1;
    ret = setsockopt (rpc_sock, IPPROTO_TCP, TCP_NODELAY, 
		    (char *) &on, sizeof (on));
    if (ret < 0)
          ;

  //vty = vty_create (libIndex, vty_sock, &su);

  /* Add read/write thread. */
  rpc_event (libIndex, RPC_WRITE, rpc_sock, NULL);
  rpc_event (libIndex, RPC_READ, rpc_sock, NULL);
 //add by qihang 
// rpc_event (libIndex, RPC_SERV, rpc_sock, NULL); 
  return 0;
}
int rpc_read (int libIndex, struct thread_rpc *thread)
{
	int i = 0;
	int pktLen,responseLen;
	unsigned char request[RPC_READ_BUF],response[RPC_READ_BUF];
	int return_param_num,return_bytes=sizeof(RPC_HEAD_SERV_ST);
	int rpc_id;
	int rpc_sock = RPC_THREAD_FD (thread);
	int offset2 = sizeof(RPC_HEAD_SERV_ST);

	memset(request,0,sizeof(request)); 
	pktLen = readRpcRequest(rpc_sock ,request);

	rpc_id = cc_rpc_get_rpc_id(request);
	
	RPCDebugOut("rpc_id = %d\n", rpc_id);
	/* Excute method and return result */
	ExcuteMethod(request,&response[offset2],&return_param_num,&return_bytes);
    	/* Generate response */
	responseLen=cc_rpc_generate_head(response,rpc_id,return_param_num,return_bytes);
	
        /* Send response to client */
       sendResponse(rpc_sock,response,responseLen);
       rpc_event (libIndex, RPC_WRITE, rpc_sock, NULL);
       rpc_event (libIndex, RPC_READ, rpc_sock, NULL);

       return 0;
}

int rpc_write (int libIndex, struct thread_rpc *thread)
{
    return 0;
}

void rpc_event (int libIndex, int event, int sock, char *vty)
{
  switch (event)
    {
    case RPC_SERV:
      rpc_thread_add_read (libIndex, master_rpc, rpc_accept, vty, sock);
      break;

    case RPC_READ:
      rpc_thread_add_read (libIndex, master_rpc, rpc_read, vty, sock);
      break;

    case RPC_WRITE:
      rpc_thread_add_write (libIndex, master_rpc, rpc_write, vty, sock);
      break;
    }
}

void rpc_serv_sock (int libIndex, unsigned short port, int family)
{
  int ret;
  union sockunion su;
  int accept_sock;

  memset (&su, 0, sizeof (union sockunion));
  su.sa.sa_family = family;

  /* Make new socket. */
  accept_sock = rpc_sockunion_stream_socket (libIndex, &su);
  if (accept_sock < 0)
  {
	return;
  }
  /* This is server, so reuse address. */
  rpc_sockopt_reuseaddr (libIndex, accept_sock);
  rpc_sockopt_reuseport (libIndex, accept_sock);
  /*sockopt_nodelay(accept_sock);*/

  /* Bind socket to universal address and given port. */
  ret = rpc_sockunion_bind (libIndex, accept_sock, &su, port, NULL);
  if (ret < 0)
    {
      close (accept_sock);	/* Avoid sd leak. */
      return;
    }

  /* Listen socket under queue 3. */
/*  ret = listen (accept_sock, 3);*/
  ret = listen (accept_sock, 0);
  if (ret < 0) 
    {
      /*zlog (libIndex, NULL, LOG_WARNING, "can't listen socket");*/
      close (accept_sock);	/* Avoid sd leak. */
      return;
    }
  printf("\r\n RPC listen port: %d \r\n", port);
  /* Add vty server event. */
  rpc_event (libIndex, RPC_SERV, accept_sock, NULL);
}

void *rpc_task()
{
    int libIndex = 0;
    struct thread_rpc thread;
    
    master_rpc = rpc_thread_master_create (libIndex);
    memset(master_rpc, 0, sizeof (struct thread_master_rpc));

    rpc_serv_sock (libIndex, RPC_SERV_PORT, AF_INET);
    CCRPCInitDone();
    printf("\r\n RPC server init okay! \r\n");
    while (rpc_thread_fetch (libIndex, master_rpc, &thread))
    {	
    		//printf("step rpc_thread_call\n");
    		rpc_thread_call (libIndex, &thread);
    		//taskDelay(1);
     }
	printf("&&&&&&&&&&&&&&&& You are dead here! &&&&&&&&&&&&&&&&&&&&&&\n");
	/* Not reached... for ever */
	exit (0);
}

pthread_t rpc_task_id = 0 ;
int main(void)
{
	rpcStatSysInfoInit();
	int  ret = pthread_create(&rpc_task_id, NULL, (void *)&rpc_task,NULL);
	if(ret < 0)
	{
		perror("pthread_create:");
		exit(-1);
	}
	else
	{
		printf("Hello the thread \n");
	}
	
	ret = pthread_join(rpc_task_id, NULL);
	if(ret < 0)
	{
		perror("pthread_join:");
	}
	printf("thread exit from main function!\n");
	return 0;
}
